package com.example.controller;

import cn.hutool.core.map.MapUtil;
import com.example.POJO.User;
import com.example.Util.JwtUtils;
import com.example.common.Result;
import com.example.common.dto.LoginDto;
import com.example.config.ESConfig;
import com.example.repository.UserRepository;
import com.google.gson.Gson;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value="/search"  )
public class Search {

    @Autowired
    UserRepository userRepository;

    @Autowired
    RestHighLevelClient esClient;

    @RequestMapping(value="/{q}", method= RequestMethod.GET    )
    public Result search(@PathVariable("q") String q) throws IOException, InterruptedException {
        System.out.println(q);
        System.out.println(q);
        System.out.println(q);
        System.out.println(q);


        // 条件查询
        SearchRequest request = new SearchRequest();
        request.indices(ESConfig.INDEICE);

        String fieldName1 = "title";
        String fieldName2 = "description";

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.multiMatchQuery(q , fieldName1, fieldName2));
        String[] excludes = {};      // 不显示 yyy 字段
        String[] includes = {"id",fieldName1, fieldName2};      // 只显示 xxx 字段
        searchSourceBuilder.fetchSource(includes, excludes);

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span  style='color:red;'   >");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field(fieldName1);
        highlightBuilder.field(fieldName2);

        searchSourceBuilder.highlighter(highlightBuilder);
        request.source(searchSourceBuilder);
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());  // 查询总条数
        System.out.println(response.getTook());   // 花费时间

//        Thread.sleep(1200);

        List<Map<String, Object>> mapList = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            //解析高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField field1= highlightFields.get(fieldName1);
            HighlightField field2= highlightFields.get(fieldName2);
            if(field1!= null){
                Text[] fragments = field1.fragments();
                StringBuilder n_field = new StringBuilder();
                for (Text fragment : fragments) {
                    n_field.append(fragment);
                }
                //高亮标题覆盖原标题
                sourceAsMap.put(fieldName1, n_field.toString());
            }
            if(field2!= null){
                Text[] fragments = field2.fragments();
                StringBuilder n_field = new StringBuilder();
                for (Text fragment : fragments) {
                    n_field.append(fragment);
                }
                //高亮标题覆盖原标题
                sourceAsMap.put(fieldName2, n_field.toString());
            }
            // 添加高亮之后的文件
            mapList.add(hit.getSourceAsMap());
        }


        for (Map<String, Object> item : mapList){
//            System.out.println(item.get(fields));
            System.out.println(item);
        }

        return Result.succ(mapList);
    }

}
